package com.vikstrom.LTimePictureViewer;

import android.util.Log;

import java.util.Calendar;
import java.util.GregorianCalendar;

/**
 * Created by vikstlu on 21.12.2013.
 */
public class Birthday {
    private static final int MILLISECONDS_IN_DAY = 1000 * 60 * 60 * 24;
    private Calendar birthday;
    private String name;
    private long numDaysToBirthday;
    private Calendar nowCal;
    private int age;

    public Birthday(String name, Calendar birthday, Calendar nowCal) {
        age = -1;
        this.name = name;
        this.birthday = birthday;
        this.nowCal = nowCal;
        numDaysToBirthday = -2;
    }

    public Calendar getBirthday() {
        return birthday;
    }

    public int getAge(Calendar nowCal) {
        if ((this.nowCal.get(Calendar.YEAR) != nowCal.get(Calendar.YEAR)) ||
                (this.nowCal.get(Calendar.MONTH) != nowCal.get(Calendar.MONTH)) ||
                (this.nowCal.get(Calendar.DAY_OF_MONTH) != nowCal.get(Calendar.DAY_OF_MONTH))){
            this.nowCal = nowCal;
            updateAge();
        } else if (age == -1) {
            updateAge();
        }
        return age;
    }

    private void updateAge() {
        age = nowCal.get(Calendar.YEAR) - birthday.get(Calendar.YEAR);
    }

    public String getName() {
        return name;
    }

    public long getNumDaysToBirthday(Calendar nowCal) {
        if ((this.nowCal.get(Calendar.YEAR) != nowCal.get(Calendar.YEAR)) ||
                (this.nowCal.get(Calendar.MONTH) != nowCal.get(Calendar.MONTH)) ||
                (this.nowCal.get(Calendar.DAY_OF_MONTH) != nowCal.get(Calendar.DAY_OF_MONTH))){
            this.nowCal = nowCal;
            updateNumDaysToBirthday();
        } else if (numDaysToBirthday == -2)
            updateNumDaysToBirthday();
        return numDaysToBirthday;
    }

    private void updateNumDaysToBirthday() {
        numDaysToBirthday = -2;
        try {
            Calendar thisYearCal = new GregorianCalendar(nowCal.get(Calendar.YEAR), birthday.get(Calendar.MONTH), birthday.get(Calendar.DAY_OF_MONTH));
            numDaysToBirthday = countDaysBetween(nowCal, thisYearCal);
        } catch (IllegalArgumentException e) {
        }
    }

    private long countDaysBetween(Calendar start, Calendar end) {
        start.set(Calendar.HOUR_OF_DAY, 0);
        start.set(Calendar.MINUTE, 0);
        start.set(Calendar.SECOND, 0);

        end.set(Calendar.HOUR_OF_DAY, 0);
        end.set(Calendar.MINUTE, 0);
        end.set(Calendar.SECOND, 0);

        if ((end.get(Calendar.DAY_OF_MONTH) == start.get(Calendar.DAY_OF_MONTH)) && (end.get(Calendar.MONTH) == start.get(Calendar.MONTH))) {
            return 0;
        } else {
            if (end.before(start)) {
                throw new IllegalArgumentException("The end date must be later than the start date");
            }

            long startTime = start.getTimeInMillis();
            //Log.d("countDaysBetween starttime", String.valueOf(startTime));

            long endTime = end.getTimeInMillis();
            //Log.d("countDaysBetween endtime", String.valueOf(endTime));

            return (endTime - startTime) / MILLISECONDS_IN_DAY + 1;
        }
    }
}
